package com.tanhua.dubbo.api;

import com.tanhua.dubbo.api.mongo.VideoApi;
import com.tanhua.dubbo.api.mongo.VideoLikeApi;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.mongo.VideoLike;
import com.tanhua.model.vo.PageResult;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@DubboService
public class VideoLikeApiImpl implements VideoLikeApi {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private VideoApi videoApi;

    /**
     * 视频点赞
     *
     * @param videoLike
     */
    @Override
    public Integer like(VideoLike videoLike) {
        ObjectId videoId = videoLike.getVideoId();
        long currentTime = System.currentTimeMillis();
        Query query = new Query(Criteria.where("userId").is(videoLike.getUserId())
                .and("videoId").is(videoId));
        if (mongoTemplate.exists(query, VideoLike.class)) {
            Update update = new Update();
            update.set("updated", currentTime);
            mongoTemplate.updateFirst(query, update, VideoLike.class);
            Query videoQuery = new Query(Criteria.where("_id").is(videoId));
            Video video = mongoTemplate.findById(videoId, Video.class);
            return video.getLikeCount();
        } else{
            videoLike.setCreated(currentTime);
            videoLike.setUpdated(currentTime);
            mongoTemplate.insert(videoLike);

            return videoApi.updateLikeCount(videoId, 1);
        }
    }

    /**
     * 视频取消点赞
     *
     * @param videoLike
     */
    @Override
    public Integer dislike(VideoLike videoLike) {
        ObjectId videoId = videoLike.getVideoId();
        Query query = new Query(Criteria.where("userId").is(videoLike.getUserId())
                .and("videoId").is(videoId));
        mongoTemplate.remove(query, VideoLike.class);

        videoApi.updateLikeCount(videoId, -1);
        Video video = mongoTemplate.findById(videoLike.getVideoId(), Video.class);
        return video.getLikeCount();
    }

    /**
     * 获得评论列表
     *
     * @param videoLike
     * @param page
     * @param pageSize
     * @return
     */
    @Override
    public PageResult<VideoLike> getComments(VideoLike videoLike, Long page, Long pageSize) {
        Query query = new Query(Criteria.where("videoId").is(videoLike.getVideoId())
                .and("type").is(videoLike.getType()));
        long count = mongoTemplate.count(query, VideoLike.class);
        long start = (page - 1) * pageSize;
        List<VideoLike> videoLikes = new ArrayList<>();
        if(count > start) {
            videoLikes = mongoTemplate.find(query, VideoLike.class);
        }
        return new PageResult<>(page, pageSize, count, videoLikes);
    }

    /**
     * 发布评论
     *
     * @param videoLike
     */
    @Override
    public void publishComments(VideoLike videoLike) {
        long currentTime = System.currentTimeMillis();
        videoLike.setCreated(currentTime);
        videoLike.setUpdated(currentTime);
        mongoTemplate.insert(videoLike);

        Query query = new Query(Criteria.where("_id").is(videoLike.getVideoId()));
        Update update = new Update();
        update.inc("commentCount", 1);
        mongoTemplate.updateFirst(query, update, Video.class);
    }

    /**
     * 用户是否喜欢动态
     *
     * @param userId
     * @param videoIds
     * @return
     */
    @Override
    public Map<ObjectId, Boolean> getHasLikes(Long userId, List<ObjectId> videoIds) {
        Query query = new Query(Criteria.where("userId").is(userId)
                .and("videoId").in(videoIds)
                .and("type").is(CommentType.LIKE.getType()));
        List<VideoLike> userLikes = mongoTemplate.find(query, VideoLike.class);
        Map<ObjectId, Boolean> resultMap = new HashMap<>();
        for (VideoLike videoLike : userLikes) {
            resultMap.put(videoLike.getVideoId(), true);
        }
        return resultMap;
    }
}
